<template>
  <BoTable
    ref="tableRef"
    :columns="columns"
    :request="_fetchList"
    show-index
    :row-selection="rowSelection"
    row-key="id"
  >
    <template #toolbars>
      <Space>
        <Button @click="onAdd">新增</Button>
        <Button
          @click="onDownload"
          :disabled="!rowSelection.selectedRowKeys.length"
          >历史数据下载</Button
        >
      </Space>
    </template>
    <template #leftContainer>
      <div class="mr-4 w-48 border-r border-[rgba(255,255,255,.3)]">
        <div class="mr-2 flex h-10 items-center justify-between">
          <h3 class="module-title mb-0 mr-7">监测列表</h3>
        </div>
        <Tree
          :tree-data="treeData"
          :selected-keys="[selectKeys]"
          :expanded-keys="expandedKeys"
          :field-names="{ key: 'id', title: 'structureName' }"
        >
          <template #title="scope">
            <span @click="() => handleSelectStructure(scope)">{{
              scope.structureName
            }}</span>
          </template>
        </Tree>
      </div>
    </template>
  </BoTable>

  <FormModal :columns="items"></FormModal>
</template>

<route lang="json">
{
  "meta": {
    "title": "测点管理"
  }
}
</route>
<script setup lang="tsx">
import { computed, onMounted, reactive, ref, useTemplateRef } from 'vue';
import { useFormModal } from '@boeyo/hooks';
import { useDicts } from '@boeyo/portal';
import { listToEnum, listToOption, treeToArray } from '@boeyo/shared';
import { BoFormProps, BoTable, BoTableProps } from '@boeyo/ui';
import { Button, Space, Tree } from 'ant-design-vue';
import dayjs from 'dayjs';
import LonLat from '@/components/LonLat/index.vue';
import {
  createMeasure,
  downloadFile,
  fetchDetail,
  fetchList,
  fetchMonitorList,
  fetchStructureTree,
  projectSelectList,
} from './api';
import Devices from './components/devices.vue';

const { pointTypeOptions, pointTypeEnum, linkTypeOptions, linkTypeEnum } =
  useDicts(['point_type', 'link_type']);

const projectOptions = ref([]);
const projectEnum = ref({});
const expandedKeys = ref([]);

const treeData = ref();
onMounted(() => {
  fetchStructureTree().then((res) => {
    treeData.value = res.data;
    expandedKeys.value = treeToArray(treeData.value).map((item) => item.id);
  });
  projectSelectList().then((res) => {
    projectOptions.value = listToOption(res.data, 'name', 'projectId');
    projectEnum.value = listToEnum(res.data, 'name', 'projectId');
  });
});

const selectKeys = ref(undefined);
const tableRef = useTemplateRef('tableRef');
let params: Record<string, any> = {};

const handleSelectStructure = (scope) => {
  const { monitoringType, id } = scope;
  params = {};
  if (id === selectKeys.value) {
    selectKeys.value = undefined;
  } else {
    selectKeys.value = id;
    switch (monitoringType) {
      case '1':
        params.netId = id;
        break;
      case '2':
        params.regionId = id;
        break;
      case '3':
        params.structureId = id;
        break;
    }
  }

  tableRef.value.refresh();
};
const _fetchList = (_params) => {
  return fetchList({ ...params, ..._params });
};
const columns = computed<BoTableProps['columns']>(() => {
  return [
    {
      title: '设备编号',
      dataIndex: 'stationId',
      hideInSearch: true,
    },
    {
      title: '测点名称',
      dataIndex: 'pointName',
    },
    {
      title: '测点位置',
      dataIndex: 'location',
      hideInSearch: true,
    },
    {
      title: '测点类型',
      dataIndex: 'pointType',
      valueType: 'select',
      valueEnum: {
        ...pointTypeEnum.value,
      },
    },
    // {
    //   title: '测点关联类型',
    //   dataIndex: 'linkType',
    //   hideInSearch: true,
    //   valueEnum: {
    //     ...linkTypeEnum.value,
    //   },
    // },
    {
      title: '经度',
      dataIndex: 'lon',
      hideInSearch: true,
    },
    {
      title: '纬度',
      dataIndex: 'lat',
      hideInSearch: true,
    },
    {
      title: '所属项目',
      dataIndex: 'projectName',
      hideInSearch: true,
    },
    {
      title: '所属监测阵',
      dataIndex: 'structureName',
      hideInSearch: true,
    },
    {
      title: '操作',
      dataIndex: 'actions',
      hideInSearch: true,
      fixed: 'right',
      actions() {
        return [
          {
            text: '详情',
            onClick(record) {
              onView(record);
            },
          },
        ];
      },
    },
  ];
});

const { FormModal, open } = useFormModal({
  size: 'middle',
  column: 2,
  formProps: {
    labelCol: { span: 7 },
    wrapperCol: { span: 17 },
  },
});

const monitorNetOptions = ref([]);
const monitorRegionOptions = ref([]);
const monitorPositionOptions = ref([]);
onMounted(() => {
  fetchMonitorList({ pid: null, monitoringType: '1' }).then((res) => {
    monitorNetOptions.value = listToOption(res.data, 'structureName', 'id');
  });
});

const updateMonitorRegionOptions = (pid) => {
  fetchMonitorList({ pid, monitoringType: '2' }).then((res) => {
    monitorRegionOptions.value = listToOption(res.data, 'structureName', 'id');
  });
};

const updateMonitorPositionOptions = (pid) => {
  fetchMonitorList({ pid, monitoringType: '3' }).then((res) => {
    monitorPositionOptions.value = res.data.map((item) => {
      return {
        label: item.structureName,
        value: item.id,
        ...item,
      };
    });
  });
};

const items = computed<BoFormProps['columns']>(() => {
  return [
    {
      title: '',
      dataIndex: '_info',
      valueType: 'input',
      colProps: { span: 24 },
      formItemRender() {
        return <div class='module-title'>监测信息</div>;
      },
    },
    {
      title: '监测网',
      dataIndex: 'netId',
      valueType: 'select',
      formItemProps: {
        rules: [{ required: true, message: '请选择监测网' }],
      },
      fieldProps(state) {
        return {
          options: monitorNetOptions.value as any,
          onChange: (val) => {
            state.regionId = undefined;
            state.structureId = undefined;
            state.projectId = undefined;
            updateMonitorRegionOptions(val);
          },
          placeholder: '请选择监测网',
        };
      },
    },
    {
      title: '监测区',
      dataIndex: 'regionId',
      valueType: 'select',
      formItemProps: {
        rules: [{ required: true, message: '请选择监测区' }],
      },
      fieldProps(state) {
        return {
          options: monitorRegionOptions.value as any,
          onChange: (val) => {
            state.structureId = undefined;
            state.projectId = undefined;
            updateMonitorPositionOptions(val);
          },
          placeholder: '请选择监测区',
        };
      },
    },
    {
      title: '监测阵',
      dataIndex: 'structureId',
      valueType: 'select',
      formItemProps: {
        rules: [{ required: true, message: '请选择监测阵' }],
      },
      fieldProps(state) {
        return {
          options: monitorPositionOptions.value as any,
          placeholder: '请选择监测阵',
          onChange(value) {
            console.log(value, monitorPositionOptions.value);
            const result = monitorPositionOptions.value.find(
              (v) => v.value === value,
            );
            state.projectId = result?.projectId ? +result.projectId : undefined;
          },
        };
      },
    },
    {
      title: '所属项目',
      dataIndex: 'projectId',
      valueType: 'select',
      fieldProps: {
        readonly: true,
        disabled: true,
        options: projectOptions.value,
        placeholder: '请选择项目',
      },
    },
    {
      title: '',
      dataIndex: '_info',
      valueType: 'input',
      colProps: { span: 24 },
      formItemRender() {
        return <div class='module-title'>测点信息</div>;
      },
    },
    {
      title: '测点名称',
      dataIndex: 'pointName',
      valueType: 'input',
      formItemProps: {
        rules: [{ required: true, message: '请输入测点名称' }],
      },
      fieldProps: {
        placeholder: '请输入测点名称',
      },
    },
    {
      title: '测点位置',
      dataIndex: 'location',
      valueType: 'input',
      formItemProps: {
        rules: [{ required: true, message: '请输入测点位置' }],
      },
      fieldProps: {
        placeholder: '请输入测点位置',
      },
    },
    {
      title: '测点类型',
      dataIndex: 'pointType',
      valueType: 'select',
      formItemProps: {
        rules: [{ required: true, message: '请选择测点类型' }],
      },
      fieldProps: {
        options: pointTypeOptions.value as any,
        placeholder: '请选择测点类型',
      },
    },
    {
      title: '经纬度',
      dataIndex: 'lon',
      valueType: 'input',
      formItemProps: {
        rules: [{ required: true, message: '请输入经度' }],
      },
      fieldProps: {
        placeholder: '请输入经度',
      },
      render(state) {
        return <LonLat v-model:lon={state.lon} v-model:lat={state.lat} />;
      },
    },
    {
      title: '',
      dataIndex: '_info',
      valueType: 'input',
      colProps: { span: 24 },
      formItemRender() {
        return <div class='module-title'>设备信息</div>;
      },
    },
    {
      title: '',
      dataIndex: 'deviceId',
      valueType: 'input',
      colProps: { span: 24 },
      formItemProps: {
        labelCol: { span: 0 },
        wrapperCol: { span: 24 },
        rules: [{ required: true, message: '请选择设备' }],
      },
      render(state) {
        return (
          <Devices
            pointId={state.id}
            stationId={state.stationId}
            v-model:value={state.deviceId}
          />
        );
      },
    },
  ];
});

const onAdd = () => {
  open({
    title: '新增',
    items: [],
    request: async function (params: any) {
      await createMeasure(params);
      tableRef.value.refresh();
    },
  });
};

const onView = async (record) => {
  const result = await fetchDetail(record.id);
  const { netId, regionId, deviceId, ...others } = result.data;
  updateMonitorRegionOptions(netId);
  updateMonitorPositionOptions(regionId);

  const { structureId, projectId, linkType } = record;

  open({
    title: (type) => (type === 'info' ? '详情' : '编辑'),
    defaultValue: {
      netId: +netId,
      regionId: +regionId,
      structureId,
      projectId,
      linkType,
      deviceId,
      ...others,
      ...record,
    },
    modalType: 'info',
    request: async function (params: any) {
      await createMeasure(params);
      // throw new Error('Function not implemented.');
      tableRef.value.refresh();
    },
  });
};

const rowSelection = reactive<BoTableProps['rowSelection']>({
  selectedRowKeys: [],
  onChange(selectedRowKeys) {
    rowSelection.selectedRowKeys = selectedRowKeys;
  },
});

const onDownload = () => {
  open({
    title: '历史数据下载',
    size: 'small',
    column: 1,
    items: [
      {
        title: '选择时间',
        valueType: 'dateRange',
        dataIndex: 'time',
        formItemProps: {
          labelCol: { style: 'width: 100px' },
          wrapperCol: { style: 'width: 100%' },
          rules: [{ required: true, message: '请选择时间' }],
        },
        fieldProps: {
          showTime: true,
          disabledDate(date) {
            return dayjs().isBefore(date);
          },
        },
      },
    ],
    request: async function ({ time }: any) {
      const [startTime, endTime] = time;

      await downloadFile({
        startTime,
        endTime,
        ids: rowSelection.selectedRowKeys,
      });
    },
  });
};
</script>
